package com.lee.util;

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 多线程测试包
 * User:liwei
 * Date:2017/9/3
 * Time:15:08
 */
public class ConcurrentTestUtils {

    /**
     * 测试多线程的方法，一般用于测试性能
     * @param threadCount
     * @param runnable
     */
    public static void concurrentTest(int threadCount,Runnable runnable){
        ExecutorService pool = Executors.newFixedThreadPool(1000);
        CountDownLatch countDownLatch = new CountDownLatch(threadCount);
        AtomicLong maxThreadTime = new AtomicLong(0);//用于统计耗时最长的线程执行时间
        AtomicLong minThreadTime = new AtomicLong(Long.MAX_VALUE);//用于统计耗时最短的线程执行时间
        AtomicLong sumThreadTime = new AtomicLong(0);

        long totalStart = System.currentTimeMillis();
        for(int i=0;i<threadCount;i++){
            pool.submit(() -> {
                long start = System.currentTimeMillis();
                runnable.run();
                long currentThreadTime = System.currentTimeMillis() - start;

                if(currentThreadTime > maxThreadTime.longValue()){
                    maxThreadTime.set(currentThreadTime);
                }

                if(currentThreadTime <= minThreadTime.longValue()){
                    minThreadTime.set(currentThreadTime);
                }
                sumThreadTime.addAndGet(currentThreadTime);
                countDownLatch.countDown();
            });
        }

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long totalTime = System.currentTimeMillis() - totalStart;
        System.out.println("-----------------------------------------------------");
        System.out.println("并发总耗时："+totalTime +"ms");
        System.out.println("每个线程平均耗时："+sumThreadTime.longValue()/threadCount+"ms");
        System.out.println("线程最大耗时："+maxThreadTime.longValue()+"ms");
        System.out.println("线程最小耗时："+minThreadTime.longValue()+"ms");
    }

    public static void main(String[] args) {
        ConcurrentTestUtils.concurrentTest(100, () -> {
            System.out.println("123");
            try {
                Thread.sleep(new Random().nextInt(3) * 1000);//0~2
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
}
